#!/usr/bin/env python
# -*- coding: utf-8 -*- 

#Kiwi Bot
#Copyright (C) 2009 Mathieu "MathX" Xhonneux
#Modified by @nge1nCorsic4 in 2011

#This program is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 2 of the License, or
#(at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License along
#with this program; if not, write to the Free Software Foundation, Inc.,
#51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import kiwi, kiwi.config, kiwi.lang, kiwi.plugin, kiwi.bd
import socket, pickle, glob, urllib2
import sqlite3

from os.path import isfile, getmtime

class Client:
	id = None
	name = None
	guid = None
	ip = None
	dns = None
	live = None
	team = -1
	rights = -1
	# weapmodes = None
	# connectionTime = kiwi.getTime()
	
class Clients:
	def __init__(self, main):
		self.lang = kiwi.lang.Lang(self,'base')
		self.main = main
		self.clientsList = []
		c = kiwi.config.configuration()
		self.alert = c.kiwi.alert
		self.bdClient = kiwi.bd.bd_client()
		# self.bdClient = kiwi.bd.bd_ban()
		self.translate = kiwi.getPath(c.lang.translate)
		self.GetTranslate()
		self.rights = self.unparseRights()
		self.main.log.info(self.lang.lang('', '10005'))
		self.main.registerHandler(kiwi.events.EVT_CLIENT_CONNECT, self.clientConnect)
		self.main.registerHandler(kiwi.events.EVT_CLIENT_DISCONNECT,self.clientDisconnect)
		self.main.registerHandler(kiwi.events.EVT_CLIENT_INFO,self.clientInfos)
		self.main.registerHandler(kiwi.events.EVT_CLIENT_UPDATE,self.clientUpdate)
	def getClientsList(self):
		list = []
		for i in self.clientsList:
			if i.rights > -1:
				list.append(i)
		return list
	def getClientById(self, id):
		list = []
		for client in self.getClientsList():
			if id == client.id:
				list.append(client)
		return list
	def getClientByFullName(self,name):
		list = []
		for client in self.getClientsList():
			if name == client.name:
				list.append(client)
		return list
	def getClientByName(self,name):
		list = []
		name = name.lower()
		for client in self.getClientsList():
			if name in client.name.lower():
				list.append(client)
		return list
	def getClientByInput(self, input):
		if input.isdigit():
			input = int(input)
			return self.getClientById(input)
		else:
			return self.getClientByName(input)
	def getClientByGUID(self,guid):
		for client in self.getClientsList():
			if guid == client.guid:
				return client
		return None
	def getClientsByLevel(self, level):
		if type(level) != int:
			return None
		list = []
		for client in self.getClientsList():
			if level == client.rights:
				list.append(client)
		return list
	def getTeams(self):
		red, blue, spec = [], [], []
		for c in self.getClientsList():
			team = int(c.team)
			if team == 1:
				red.append(c)
			elif team == 2:
				blue.append(c)
			elif team == 3:
				spec.append(c)
		return red, blue, spec
	def clientConnect(self, event):
		for client in self.clientsList:
			if client.id == event.id:
				self.clientsList.remove(client)
		c = Client()
		c.id = event.id
		self.clientsList.append(c)
	def clientDisconnect(self, event):
		id = event.id
		for client in self.clientsList:
			if client.id == id:
				self.clientsList.remove(client)
	def clientInfos(self, event):
		data = {'cl_guid':'guid','name':'name','ip':'ip'}
		for client in self.clientsList:
			if client.id == event.id:
				for d in data:
					if d in event.vars:
						setattr(client,data[d],event.vars[d])
					else:
						setattr(client,data[d],None)
				client.ip = client.ip.split(':')[0]
				BDclient = self.bdClient.getTableByGuid(client.guid)
				if BDclient:
					client.live = BDclient['live']
					client.dns = BDclient['dns']
					client.rights = BDclient['rights']
				else:
					client.rights = 0
					client.live = self.clientState(client.ip)
				# if type(client.ip) == str:
					try:
						# if client.live == 'fr': 
						client.dns = socket.gethostbyaddr(client.ip)[0]
					except socket.herror:
						client.dns = None
					except socket.gaierror:
						client.dns = None
					self.bdClient.writeTable(client)
				self.clientsList[self.clientsList.index(client)] = client
				if client.rights >= 10:
					if self.alert == "on":
						self.Alert(client.id)
				return
		self.clientConnect(event)
		self.clientInfos(event)
	def clientUpdate(self, event):
		data = {'n':'name','t':'team'}
		for client in self.clientsList:
			if client.id == event.id:
				for d in data:
					if d in event.vars:
						setattr(client,data[d],event.vars[d])
					else:
						setattr(client,data[d],None)
				self.clientsList[self.clientsList.index(client)] = client
	def GetTranslate(self):
		self.worldIp = {}
		for c in self.translate.split():
			path = kiwi.getPath('@kiwi/files/')+c+'.txt'
			if not isfile(path):
				continue
			f=open(path,'r')
			self.worldIp[c] = f.readlines()
			f.close()
	def clientState(self, client_ip):
		ip = client_ip.split('.')
		d = ''
		for a in ip:
			if len(a) == 3:
				pass
			elif len(a) == 2:
				a='0'+a
			elif len(a) == 1:
				a='00'+a
			d+=a
		ip = int(d)
		for a in self.worldIp:
			for b in self.worldIp[a]:
				b=b.strip()
				list=b.split(',')
				if ip >= int(list[0]) and ip <= int(list[1]):
					return a
		return 'en'
	def unparseRights(self):
		try:
			data = {}
			list = self.bdClient.getTableAll()
			# print list
			# print 'result ok'
			for a in list:
				# print a['guid'],a['name'],a['rights']
				data[a['guid']]=(a['name'],a['rights'])
			# print 'data ok'
			return data
		except:
			self.main.log.warn(self.lang.lang('', '10006'))
			return {}
	def parseRights(self):
		try:
			f = file(self.path,'w')
			data = pickle.dump(self.rights,f)
			f.close()
		except Exception:
			self.main.log.warn(self.lang.lang('', '10007'))
	def getRights(self, guid):
		for i in self.rights:
			if i == guid:
				if type(self.rights[i]) == int:
					return self.rights[i]
				else:
					return self.rights[i][1]
		return 0
	def setRights(self, guid, name, level):
		if guid in self.rights:
			if level == 0:
				del self.rights[guid]
			else:
				self.rights[guid] = name, level
		else:
			if level == 0:
				return False
			else:
				self.rights[guid] = name, level
		# self.parseRights()
		client = self.getClientByGUID(guid)
		for c in self.clientsList:
			if c == client:
				self.clientsList[self.clientsList.index(c)].rights = level
				self.bdClient.updateTable(client)
				# print client.rights
				return True
		return False
	def request(self,page):
		req = urllib2.Request(page)
		handle = urllib2.urlopen(req)
		return handle.read()
	def Alert(self, id):
		repo = 'http://kiwi.clan-fun.fr/depot/kiwi_v3_match/version'
		path = kiwi.getPath('@version')
		try:
			version = self.request(repo)
			if isfile(path):
				f = file(path,'r')
				data = f.read()
				f.close()
				if version == data:
					return
			# print 'erreur mise jour => ', path
			self.main.rcon.send('tell %s ^1Une mise a jour de kiwi est disponible: ^7%s'%(id,version))
		except urllib2.HTTPError:
			print '*Erreur lors du telechargement du fichier de definition...'						